package degreeAndSyllabus;

import java.util.LinkedList;
import java.util.List;

import subjectAndProfessorship.Subject;
import exception.CorrelativaNoExisteException;
import exception.CorrelativaYaExistenteException;

/**
 * @author Nati
 */
public class SubjectInPlan implements Comparable<SubjectInPlan>{ // materia en plan
	/* ******************************** Variables ******************************** */
	private Subject materia;
	private List <SubjectInPlan> materiasCorrelativas = new LinkedList<SubjectInPlan>();	
	private SubjectType type;
	private int year; 
	private Syllabus syllabus; 
	private List<SubjectInPlan> materiasEquivalentes = new LinkedList<SubjectInPlan>();	

	/* ******************************* Constructor ******************************* */
	public SubjectInPlan(Subject materia, int year) { 
		this.materia = materia;
		this.year = year; 
	}
	
	/* ********************************* Metodos ********************************* */
	/**
	 * @param correlativa
	 * @throws CorrelativaYaExistenteException
	 * @
	 * Agrego una materia correlativa a la materia del plan en caso que esta no se encuentre, sino lanza una exception
	 */
	public void addCorrelative (SubjectInPlan correlativa) throws CorrelativaYaExistenteException{
		if (this.materiasCorrelativas.contains(correlativa)){
			throw new CorrelativaYaExistenteException("La materia correlativa ya se encuentra agregada"); 
		}else {
			this.materiasCorrelativas.add(correlativa); 
		}
	}
	
	
	public void addEquivalente(SubjectInPlan materiaEquivalente){
		this.getMateriasEquivalentes().add(materiaEquivalente);
		
	}
	
	public void removeEquivalente(SubjectInPlan materiaEquivalente){
		this.getMateriasEquivalentes().remove(materiaEquivalente);
		
	}
	
	/**
	 * @param correlativa
	 * @throws CorrelativaNoExisteException
	 * @
	 * Elimino una materia correlativa de mi lista, en caso que no exista dicha materia lanzo exception
	 */
	public void removeCorrelative (SubjectInPlan correlative)throws CorrelativaNoExisteException{
		if (this.materiasCorrelativas.contains(correlative)){
			this.materiasCorrelativas.remove(correlative); 			
		}else{
			throw new CorrelativaNoExisteException("La materia correlativa no se encuentra agregada"); 
		}
	}
	
	/**
	 * Redefino el metodo compareTo, para que despues ordene por este criterio.
	 */
	public int compareTo(SubjectInPlan anotherSubjectInPlan) {
		return Integer.valueOf(anotherSubjectInPlan.materia.getDifficult()).compareTo(Integer.valueOf(this.materia.getDifficult()));
	}

	public boolean aproboMateriasObligatorias(EnrolledInDegree student, Degree degree) {
		return student.materiasAprobadas().containsAll(this.syllabus.getObligatorias());
	}
	
	/* ******************************** Get & Set ******************************** */
	public Subject getMateria() {
		return materia;
	}
	
	public void setMateria(Subject materia) {
		this.materia = materia;
	}
	
	public List<SubjectInPlan> getMateriasCorrelativas() {
		return materiasCorrelativas;
	}
	
	public void setMateriasCorrelativas(List<SubjectInPlan> materiasCorrelativas) {
		this.materiasCorrelativas = materiasCorrelativas;
	}

	public void setType(SubjectType type) {
		this.type = type;
	}

	public SubjectType getType() {
		return type;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public int getYear() {
		return year;
	}

	public void setSyllabus(Syllabus syllabus) {
		this.syllabus = syllabus;
	}

	public Syllabus getSyllabus() {
		return syllabus;
	}

	public void setMateriasEquivalentes(List<SubjectInPlan> materiasEquivalentes) {
		this.materiasEquivalentes = materiasEquivalentes;
	}

	public List<SubjectInPlan> getMateriasEquivalentes() {
		return materiasEquivalentes;
	}
}
